<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="author" content="Patrick T. Komiske III" /><link rel="canonical" href="https://thaler-lab.github.io/Wasserstein/examples/" />
      <link rel="shortcut icon" href="../img/favicon.ico" />
    <title>C++ Examples - Wasserstein</title>
    <link rel="stylesheet" href="../css/theme.css" />
    <link rel="stylesheet" href="../css/theme_extra.css" />
        <link href="../css/eftheme.css" rel="stylesheet" />
        <link href="../css/pygmentize_friendly.css" rel="stylesheet" />

      <script>
        // Current page data
        var mkdocs_page_name = "C++ Examples";
        var mkdocs_page_input_path = "examples.md";
        var mkdocs_page_url = "/Wasserstein/examples/";
      </script>

    <script src="../js/jquery-3.6.0.min.js" defer></script>
    <!--[if lt IE 9]>
      <script src="../js/html5shiv.min.js"></script>
    <![endif]-->
      <script>
        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
        m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
        })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

        ga('create', 'UA-122962541-3', 'Wasserstein');
        ga('send', 'pageview');
      </script>

</head>

<body class="wy-body-for-nav" role="document">

  <div class="wy-grid-for-nav">
    <nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
    <div class="wy-side-scroll">
      <div class="wy-side-nav-search">
  <a href="..">
    <div class="eflogo">
      <img src="../img/eflogowhite.png"  class="eflogo-img"> Wasserstein
    </div>
  </a><div role="search">
  <form id ="rtd-search-form" class="wy-form" action="../search.html" method="get">
      <input type="text" name="q" placeholder="Search docs" title="Type search term here" />
  </form>
</div>
      </div>

      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
              <ul>
                <li class="toctree-l1"><a class="reference internal" href="..">Home</a>
                </li>
              </ul>
              <p class="caption"><span class="caption-text">Getting Started</span></p>
              <ul class="current">
                  <li class="toctree-l1"><a class="reference internal" href="../installation/">Installation</a>
                  </li>
                  <li class="toctree-l1"><a class="reference internal" href="../demos/">Python Demos</a>
                  </li>
                  <li class="toctree-l1 current"><a class="reference internal current" href="./">C++ Examples</a>
    <ul class="current">
    <li class="toctree-l2"><a class="reference internal" href="#emd_examplecpp">emd_example.cpp</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#pairwise_emds_examplecpp">pairwise_emds_example.cpp</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#serialization_examplecpp">serialization_example.cpp</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#theory_space_examplecpp">theory_space_example.cpp</a>
    </li>
    </ul>
                  </li>
                  <li class="toctree-l1"><a class="reference internal" href="../faqs/">FAQs</a>
                  </li>
                  <li class="toctree-l1"><a class="reference internal" href="../releases/">Release Notes</a>
                  </li>
              </ul>
              <p class="caption"><span class="caption-text">Documentation</span></p>
              <ul>
                  <li class="toctree-l1"><a class="reference internal" href="../docs/emd/">EMD</a>
                  </li>
                  <li class="toctree-l1"><a class="reference internal" href="../docs/emds/">PairwiseEMD</a>
                  </li>
                  <li class="toctree-l1"><a class="reference internal" href="../docs/externalemdhandler/">External EMD Handlers</a>
                  </li>
                  <li class="toctree-l1"><a class="reference internal" href="../docs/event/">Events</a>
                  </li>
                  <li class="toctree-l1"><a class="reference internal" href="../docs/pairwisedistance/">Pairwise Distance</a>
                  </li>
                  <li class="toctree-l1"><a class="reference internal" href="../docs/utils/">Utils</a>
                  </li>
              </ul>
      </div>
    </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
      <nav class="wy-nav-top" role="navigation" aria-label="Mobile navigation menu">
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="..">Wasserstein</a>

      </nav>
      <div class="wy-nav-content">
        <div class="rst-content"><div role="navigation" aria-label="breadcrumbs navigation">
  <ul class="wy-breadcrumbs">
    <li><a href=".." class="icon icon-home" alt="Docs"></a> &raquo;</li>
          <li>Getting Started &raquo;</li><li>C++ Examples</li>
    <li class="wy-breadcrumbs-aside">
    </li>
  </ul>
  <hr/>
</div>

          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
            <div class="section" itemprop="articleBody">

                <h1 id="examples">Examples</h1>
<p>There are 4 C++ examples provided for the Wasserstein package. They can be <a href="https://github.com/thaler-lab/Wasserstein/tree/master/examples">downloaded from GitHub</a> with associated files and a Makefile.</p>
<h3 id="emd_examplecpp">emd_example.cpp</h3>
<div class="codehilite"><pre><span></span><code><span class="c1">//------------------------------------------------------------------------</span>
<span class="c1">// This file is part of Wasserstein, a C++ library with a Python wrapper</span>
<span class="c1">// that computes the Wasserstein/EMD distance. If you use it for academic</span>
<span class="c1">// research, please cite or acknowledge the following works:</span>
<span class="c1">//</span>
<span class="c1">//   - Komiske, Metodiev, Thaler (2019) arXiv:1902.02346</span>
<span class="c1">//       https://doi.org/10.1103/PhysRevLett.123.041801</span>
<span class="c1">//   - Komiske, Metodiev, Thaler (2020) arXiv:2004.04159</span>
<span class="c1">//       https://doi.org/10.1007/JHEP07%282020%29006</span>
<span class="c1">//   - Boneel, van de Panne, Paris, Heidrich (2011)</span>
<span class="c1">//       https://doi.org/10.1145/2070781.2024192</span>
<span class="c1">//   - LEMON graph library https://lemon.cs.elte.hu/trac/lemon</span>
<span class="c1">//</span>
<span class="c1">// Copyright (C) 2019-2021 Patrick T. Komiske III</span>
<span class="c1">// </span>
<span class="c1">// This program is free software: you can redistribute it and/or modify</span>
<span class="c1">// it under the terms of the GNU General Public License as published by</span>
<span class="c1">// the Free Software Foundation, either version 3 of the License, or</span>
<span class="c1">// (at your option) any later version.</span>
<span class="c1">// </span>
<span class="c1">// This program is distributed in the hope that it will be useful,</span>
<span class="c1">// but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1">// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<span class="c1">// GNU General Public License for more details.</span>
<span class="c1">// </span>
<span class="c1">// You should have received a copy of the GNU General Public License</span>
<span class="c1">// along with this program.  If not, see &lt;https://www.gnu.org/licenses/&gt;.</span>
<span class="c1">//------------------------------------------------------------------------</span>

<span class="c1">// Wasserstein library</span>
<span class="cp">#include</span> <span class="cpf">&quot;Wasserstein.hh&quot;</span><span class="cp"></span>

<span class="c1">// classes and functions for reading/preparing events</span>
<span class="cp">#include</span> <span class="cpf">&quot;ExampleUtils.hh&quot;</span><span class="cp"></span>

<span class="c1">// `EMDFloat64` uses `double` for the floating-point type</span>
<span class="c1">// first template parameter is an Event type, second is a PairwiseDistance type</span>
<span class="k">using</span> <span class="n">EMD</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">EMDFloat64</span><span class="o">&lt;</span><span class="n">emd</span><span class="o">::</span><span class="n">EuclideanEvent2D</span><span class="p">,</span> <span class="n">emd</span><span class="o">::</span><span class="n">YPhiParticleDistance</span><span class="o">&gt;</span><span class="p">;</span>

<span class="c1">// the `EuclideanParticle[N]D` classes provide a simple container for weighted particles</span>
<span class="k">using</span> <span class="n">EMDParticle</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">EuclideanParticle2D</span><span class="o">&lt;&gt;</span><span class="p">;</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">**</span> <span class="n">argv</span><span class="p">)</span> <span class="p">{</span>

  <span class="c1">// load events</span>
  <span class="n">EventProducer</span> <span class="o">*</span> <span class="n">evp</span><span class="p">(</span><span class="n">load_events</span><span class="p">(</span><span class="n">argc</span><span class="p">,</span> <span class="n">argv</span><span class="p">));</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">evp</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span>
    <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>

  <span class="c1">// demonstrate calculating single EMDs</span>
  <span class="n">EMD</span> <span class="n">emd_obj</span><span class="p">(</span><span class="mf">0.4</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nb">true</span><span class="p">);</span>

  <span class="c1">// preprocess events to center</span>
  <span class="n">emd_obj</span><span class="p">.</span><span class="n">preprocess</span><span class="o">&lt;</span><span class="n">emd</span><span class="o">::</span><span class="n">CenterWeightedCentroid</span><span class="o">&gt;</span><span class="p">();</span>

  <span class="c1">// print description</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">emd_obj</span><span class="p">.</span><span class="n">description</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>

  <span class="c1">// container to hold emd values</span>
  <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">&gt;</span> <span class="n">emds</span><span class="p">;</span>

  <span class="c1">// loop over events and compute the EMD between each successive pair</span>
  <span class="n">evp</span><span class="o">-&gt;</span><span class="n">reset</span><span class="p">();</span>
  <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>

    <span class="c1">// get first event</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">evp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">())</span> <span class="k">break</span><span class="p">;</span>
    <span class="k">auto</span> <span class="n">event0</span><span class="p">(</span><span class="n">convert2event</span><span class="o">&lt;</span><span class="n">EMDParticle</span><span class="o">&gt;</span><span class="p">(</span><span class="n">evp</span><span class="o">-&gt;</span><span class="n">particles</span><span class="p">()));</span>

    <span class="c1">// get second event</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">evp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">())</span> <span class="k">break</span><span class="p">;</span>
    <span class="k">auto</span> <span class="n">event1</span><span class="p">(</span><span class="n">convert2event</span><span class="o">&lt;</span><span class="n">EMDParticle</span><span class="o">&gt;</span><span class="p">(</span><span class="n">evp</span><span class="o">-&gt;</span><span class="n">particles</span><span class="p">()));</span>

    <span class="c1">// compute emd and add it to vector</span>
    <span class="n">emds</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">emd_obj</span><span class="p">(</span><span class="n">event0</span><span class="p">,</span> <span class="n">event1</span><span class="p">));</span>
  <span class="p">}</span>

  <span class="c1">// get max and min EMD value</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span>
            <span class="o">&lt;&lt;</span> <span class="n">emds</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="s">&quot; EMDs computed</span><span class="se">\n</span><span class="s">&quot;</span>
            <span class="o">&lt;&lt;</span> <span class="s">&quot;Min. EMD - &quot;</span> <span class="o">&lt;&lt;</span> <span class="o">*</span><span class="n">std</span><span class="o">::</span><span class="n">min_element</span><span class="p">(</span><span class="n">emds</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">emds</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span>
            <span class="o">&lt;&lt;</span> <span class="s">&quot;Max. EMD - &quot;</span> <span class="o">&lt;&lt;</span> <span class="o">*</span><span class="n">std</span><span class="o">::</span><span class="n">max_element</span><span class="p">(</span><span class="n">emds</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">emds</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span>
            <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span><span class="p">;</span>

  <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>

<h3 id="pairwise_emds_examplecpp">pairwise_emds_example.cpp</h3>
<div class="codehilite"><pre><span></span><code><span class="c1">//------------------------------------------------------------------------</span>
<span class="c1">// This file is part of Wasserstein, a C++ library with a Python wrapper</span>
<span class="c1">// that computes the Wasserstein/EMD distance. If you use it for academic</span>
<span class="c1">// research, please cite or acknowledge the following works:</span>
<span class="c1">//</span>
<span class="c1">//   - Komiske, Metodiev, Thaler (2019) arXiv:1902.02346</span>
<span class="c1">//       https://doi.org/10.1103/PhysRevLett.123.041801</span>
<span class="c1">//   - Komiske, Metodiev, Thaler (2020) arXiv:2004.04159</span>
<span class="c1">//       https://doi.org/10.1007/JHEP07%282020%29006</span>
<span class="c1">//   - Boneel, van de Panne, Paris, Heidrich (2011)</span>
<span class="c1">//       https://doi.org/10.1145/2070781.2024192</span>
<span class="c1">//   - LEMON graph library https://lemon.cs.elte.hu/trac/lemon</span>
<span class="c1">//</span>
<span class="c1">// Copyright (C) 2019-2021 Patrick T. Komiske III</span>
<span class="c1">// </span>
<span class="c1">// This program is free software: you can redistribute it and/or modify</span>
<span class="c1">// it under the terms of the GNU General Public License as published by</span>
<span class="c1">// the Free Software Foundation, either version 3 of the License, or</span>
<span class="c1">// (at your option) any later version.</span>
<span class="c1">// </span>
<span class="c1">// This program is distributed in the hope that it will be useful,</span>
<span class="c1">// but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1">// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<span class="c1">// GNU General Public License for more details.</span>
<span class="c1">// </span>
<span class="c1">// You should have received a copy of the GNU General Public License</span>
<span class="c1">// along with this program.  If not, see &lt;https://www.gnu.org/licenses/&gt;.</span>
<span class="c1">//------------------------------------------------------------------------</span>

<span class="c1">// Wasserstein library</span>
<span class="cp">#include</span> <span class="cpf">&quot;Wasserstein.hh&quot;</span><span class="cp"></span>

<span class="c1">// classes and functions for reading/preparing events</span>
<span class="cp">#include</span> <span class="cpf">&quot;ExampleUtils.hh&quot;</span><span class="cp"></span>

<span class="c1">// `EMDFloat64` uses `double` for the floating-point type</span>
<span class="c1">// first template parameter is an Event type, second is a PairwiseDistance type</span>
<span class="k">using</span> <span class="n">EMD</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">EMDFloat64</span><span class="o">&lt;</span><span class="n">emd</span><span class="o">::</span><span class="n">EuclideanEvent2D</span><span class="p">,</span> <span class="n">emd</span><span class="o">::</span><span class="n">YPhiParticleDistance</span><span class="o">&gt;</span><span class="p">;</span>

<span class="c1">// `PairwiseEMD` is a templated class accepting a fully qualified `EMD` type</span>
<span class="k">using</span> <span class="n">PairwiseEMD</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">PairwiseEMD</span><span class="o">&lt;</span><span class="n">EMD</span><span class="o">&gt;</span><span class="p">;</span>

<span class="c1">// empty angle brackets use the default floating-point type `double`</span>
<span class="k">using</span> <span class="n">CorrelationDimension</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">CorrelationDimension</span><span class="o">&lt;&gt;</span><span class="p">;</span>

<span class="c1">// the `EuclideanParticle[N]D` classes provide a simple container for weighted particles</span>
<span class="k">using</span> <span class="n">EMDParticle</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">EuclideanParticle2D</span><span class="o">&lt;&gt;</span><span class="p">;</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">**</span> <span class="n">argv</span><span class="p">)</span> <span class="p">{</span>

  <span class="c1">// load events</span>
  <span class="n">EventProducer</span> <span class="o">*</span> <span class="n">evp</span><span class="p">(</span><span class="n">load_events</span><span class="p">(</span><span class="n">argc</span><span class="p">,</span> <span class="n">argv</span><span class="p">));</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">evp</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span>
    <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>

  <span class="c1">// demonstrate calculating pairwise EMDs</span>
  <span class="n">PairwiseEMD</span> <span class="n">pairwise_emd_obj</span><span class="p">(</span><span class="mf">0.4</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>

  <span class="c1">// preprocess events to center</span>
  <span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">preprocess</span><span class="o">&lt;</span><span class="n">emd</span><span class="o">::</span><span class="n">CenterWeightedCentroid</span><span class="o">&gt;</span><span class="p">();</span>

  <span class="c1">// print description</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">description</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>

  <span class="c1">// get vector of events</span>
  <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">EMDParticle</span><span class="o">&gt;&gt;</span> <span class="n">events</span><span class="p">;</span>

  <span class="c1">// loop over events and compute the EMD between each successive pair</span>
  <span class="n">evp</span><span class="o">-&gt;</span><span class="n">reset</span><span class="p">();</span>
  <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">1000</span> <span class="o">&amp;&amp;</span> <span class="n">evp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
    <span class="n">events</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">convert2event</span><span class="o">&lt;</span><span class="n">EMDParticle</span><span class="o">&gt;</span><span class="p">(</span><span class="n">evp</span><span class="o">-&gt;</span><span class="n">particles</span><span class="p">()));</span>

  <span class="c1">// run computation</span>
  <span class="n">pairwise_emd_obj</span><span class="p">(</span><span class="n">events</span><span class="p">);</span>

  <span class="c1">// get max and min EMD value</span>
  <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">&gt;</span> <span class="o">&amp;</span> <span class="n">emds</span><span class="p">(</span><span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">emds</span><span class="p">(</span><span class="nb">true</span><span class="p">));</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;Min. EMD - &quot;</span> <span class="o">&lt;&lt;</span> <span class="o">*</span><span class="n">std</span><span class="o">::</span><span class="n">min_element</span><span class="p">(</span><span class="n">emds</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">emds</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span>
            <span class="o">&lt;&lt;</span> <span class="s">&quot;Max. EMD - &quot;</span> <span class="o">&lt;&lt;</span> <span class="o">*</span><span class="n">std</span><span class="o">::</span><span class="n">max_element</span><span class="p">(</span><span class="n">emds</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">emds</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span>
            <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span><span class="p">;</span>

  <span class="c1">// setup correlation dimension</span>
  <span class="n">CorrelationDimension</span> <span class="n">corrdim</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="mf">10.</span><span class="p">,</span> <span class="mf">250.</span><span class="p">);</span>
  <span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">set_external_emd_handler</span><span class="p">(</span><span class="n">corrdim</span><span class="p">);</span>

  <span class="c1">// rerun computation</span>
  <span class="n">pairwise_emd_obj</span><span class="p">(</span><span class="n">events</span><span class="p">);</span>

  <span class="c1">// print out correlation dimensions</span>
  <span class="k">auto</span> <span class="n">corrdims</span><span class="p">(</span><span class="n">corrdim</span><span class="p">.</span><span class="n">corrdims</span><span class="p">());</span>
  <span class="k">auto</span> <span class="n">corrdim_bins</span><span class="p">(</span><span class="n">corrdim</span><span class="p">.</span><span class="n">corrdim_bins</span><span class="p">());</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">EMD         Corr. Dim.  Error</span><span class="se">\n</span><span class="s">&quot;</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">left</span><span class="p">;</span>
  <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">corrdims</span><span class="p">.</span><span class="n">first</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">setw</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">corrdim_bins</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
              <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">setw</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">corrdims</span><span class="p">.</span><span class="n">first</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
              <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">setw</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">corrdims</span><span class="p">.</span><span class="n">second</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
              <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span><span class="p">;</span>

  <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>

<h3 id="serialization_examplecpp">serialization_example.cpp</h3>
<div class="codehilite"><pre><span></span><code><span class="c1">//------------------------------------------------------------------------</span>
<span class="c1">// This file is part of Wasserstein, a C++ library with a Python wrapper</span>
<span class="c1">// that computes the Wasserstein/EMD distance. If you use it for academic</span>
<span class="c1">// research, please cite or acknowledge the following works:</span>
<span class="c1">//</span>
<span class="c1">//   - Komiske, Metodiev, Thaler (2019) arXiv:1902.02346</span>
<span class="c1">//       https://doi.org/10.1103/PhysRevLett.123.041801</span>
<span class="c1">//   - Komiske, Metodiev, Thaler (2020) arXiv:2004.04159</span>
<span class="c1">//       https://doi.org/10.1007/JHEP07%282020%29006</span>
<span class="c1">//   - Boneel, van de Panne, Paris, Heidrich (2011)</span>
<span class="c1">//       https://doi.org/10.1145/2070781.2024192</span>
<span class="c1">//   - LEMON graph library https://lemon.cs.elte.hu/trac/lemon</span>
<span class="c1">//</span>
<span class="c1">// Copyright (C) 2019-2021 Patrick T. Komiske III</span>
<span class="c1">// </span>
<span class="c1">// This program is free software: you can redistribute it and/or modify</span>
<span class="c1">// it under the terms of the GNU General Public License as published by</span>
<span class="c1">// the Free Software Foundation, either version 3 of the License, or</span>
<span class="c1">// (at your option) any later version.</span>
<span class="c1">// </span>
<span class="c1">// This program is distributed in the hope that it will be useful,</span>
<span class="c1">// but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1">// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<span class="c1">// GNU General Public License for more details.</span>
<span class="c1">// </span>
<span class="c1">// You should have received a copy of the GNU General Public License</span>
<span class="c1">// along with this program.  If not, see &lt;https://www.gnu.org/licenses/&gt;.</span>
<span class="c1">//------------------------------------------------------------------------</span>

<span class="c1">// Wasserstein library</span>
<span class="cp">#define WASSERSTEIN_SERIALIZATION</span>
<span class="cp">#include</span> <span class="cpf">&quot;Wasserstein.hh&quot;</span><span class="cp"></span>

<span class="c1">// classes and functions for reading/preparing events</span>
<span class="cp">#include</span> <span class="cpf">&quot;ExampleUtils.hh&quot;</span><span class="cp"></span>

<span class="c1">// `EMDFloat64` uses `double` for the floating-point type</span>
<span class="c1">// first template parameter is an Event type, second is a PairwiseDistance type</span>
<span class="k">using</span> <span class="n">EMD</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">EMDFloat64</span><span class="o">&lt;</span><span class="n">emd</span><span class="o">::</span><span class="n">EuclideanEvent2D</span><span class="p">,</span> <span class="n">emd</span><span class="o">::</span><span class="n">YPhiParticleDistance</span><span class="o">&gt;</span><span class="p">;</span>

<span class="c1">// `PairwiseEMD` is a templated class accepting a fully qualified `EMD` type</span>
<span class="k">using</span> <span class="n">PairwiseEMD</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">PairwiseEMD</span><span class="o">&lt;</span><span class="n">EMD</span><span class="o">&gt;</span><span class="p">;</span>

<span class="c1">// empty angle brackets use the default floating-point type `double`</span>
<span class="k">using</span> <span class="n">CorrelationDimension</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">CorrelationDimension</span><span class="o">&lt;&gt;</span><span class="p">;</span>

<span class="c1">// the `EuclideanParticle[N]D` classes provide a simple container for weighted particles</span>
<span class="k">using</span> <span class="n">EMDParticle</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">EuclideanParticle2D</span><span class="o">&lt;&gt;</span><span class="p">;</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">**</span> <span class="n">argv</span><span class="p">)</span> <span class="p">{</span>

  <span class="c1">// load events</span>
  <span class="n">EventProducer</span> <span class="o">*</span> <span class="n">evp</span><span class="p">(</span><span class="n">load_events</span><span class="p">(</span><span class="n">argc</span><span class="p">,</span> <span class="n">argv</span><span class="p">));</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">evp</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span>
    <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>

  <span class="c1">////////////////////////////</span>
  <span class="c1">// EMD Serialization</span>
  <span class="c1">////////////////////////////</span>

  <span class="c1">// demonstrate calculating single EMDs</span>
  <span class="n">EMD</span> <span class="n">emd_obj</span><span class="p">(</span><span class="mf">0.4</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nb">true</span><span class="p">);</span>

  <span class="c1">// preprocess events to center</span>
  <span class="n">emd_obj</span><span class="p">.</span><span class="n">preprocess</span><span class="o">&lt;</span><span class="n">emd</span><span class="o">::</span><span class="n">CenterWeightedCentroid</span><span class="o">&gt;</span><span class="p">();</span>

  <span class="c1">// print description</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">emd_obj</span><span class="p">.</span><span class="n">description</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>

  <span class="c1">// serialize</span>
  <span class="n">std</span><span class="o">::</span><span class="n">stringstream</span> <span class="n">ss</span><span class="p">;</span>
  <span class="n">boost</span><span class="o">::</span><span class="n">archive</span><span class="o">::</span><span class="n">text_oarchive</span> <span class="n">oa</span><span class="p">(</span><span class="n">ss</span><span class="p">);</span>
  <span class="n">oa</span> <span class="o">&lt;&lt;</span> <span class="n">emd_obj</span><span class="p">;</span>

  <span class="c1">// extract</span>
  <span class="n">boost</span><span class="o">::</span><span class="n">archive</span><span class="o">::</span><span class="n">text_iarchive</span> <span class="n">ia</span><span class="p">(</span><span class="n">ss</span><span class="p">);</span>
  <span class="n">EMD</span> <span class="n">new_emd_obj</span><span class="p">;</span>
  <span class="n">ia</span> <span class="o">&gt;&gt;</span> <span class="n">new_emd_obj</span><span class="p">;</span>

  <span class="c1">// print EMD description</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">new_emd_obj</span><span class="p">.</span><span class="n">description</span><span class="p">()</span>
            <span class="o">&lt;&lt;</span> <span class="s">&quot;Note that preprocessors are not currently preserved in serialized objects&quot;</span>
            <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>

  <span class="c1">/////////////////////////////////////////////////////</span>
  <span class="c1">// PairwiseEMD and CorrelationDimension Serialization</span>
  <span class="c1">/////////////////////////////////////////////////////</span>

  <span class="c1">// demonstrate calculating pairwise EMDs</span>
  <span class="n">PairwiseEMD</span> <span class="n">pairwise_emd_obj</span><span class="p">(</span><span class="mf">0.4</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>

  <span class="c1">// preprocess events to center</span>
  <span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">preprocess</span><span class="o">&lt;</span><span class="n">emd</span><span class="o">::</span><span class="n">CenterWeightedCentroid</span><span class="o">&gt;</span><span class="p">();</span>

  <span class="c1">// print description</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">description</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>

  <span class="c1">// get vector of events</span>
  <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">EMDParticle</span><span class="o">&gt;&gt;</span> <span class="n">events</span><span class="p">;</span>

  <span class="c1">// loop over events and compute the EMD between each successive pair</span>
  <span class="n">evp</span><span class="o">-&gt;</span><span class="n">reset</span><span class="p">();</span>
  <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">1000</span> <span class="o">&amp;&amp;</span> <span class="n">evp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
    <span class="n">events</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">convert2event</span><span class="o">&lt;</span><span class="n">EMDParticle</span><span class="o">&gt;</span><span class="p">(</span><span class="n">evp</span><span class="o">-&gt;</span><span class="n">particles</span><span class="p">()));</span>

  <span class="c1">// setup correlation dimension</span>
  <span class="n">CorrelationDimension</span> <span class="n">corrdim</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="mf">10.</span><span class="p">,</span> <span class="mf">250.</span><span class="p">);</span>
  <span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">set_external_emd_handler</span><span class="p">(</span><span class="n">corrdim</span><span class="p">);</span>

  <span class="c1">// run computation</span>
  <span class="n">pairwise_emd_obj</span><span class="p">(</span><span class="n">events</span><span class="p">);</span>

  <span class="c1">// serialize</span>
  <span class="n">std</span><span class="o">::</span><span class="n">stringstream</span> <span class="n">ss2</span><span class="p">;</span>
  <span class="n">boost</span><span class="o">::</span><span class="n">archive</span><span class="o">::</span><span class="n">text_oarchive</span> <span class="n">oa2</span><span class="p">(</span><span class="n">ss2</span><span class="p">);</span>
  <span class="n">oa2</span> <span class="o">&lt;&lt;</span> <span class="n">pairwise_emd_obj</span> <span class="o">&lt;&lt;</span> <span class="n">corrdim</span><span class="p">;</span>

  <span class="c1">// define empty objects</span>
  <span class="n">PairwiseEMD</span> <span class="n">new_pairwise_emd_obj</span><span class="p">;</span>
  <span class="n">CorrelationDimension</span> <span class="n">new_corrdim</span><span class="p">;</span>

  <span class="c1">// extract</span>
  <span class="n">boost</span><span class="o">::</span><span class="n">archive</span><span class="o">::</span><span class="n">text_iarchive</span> <span class="n">ia2</span><span class="p">(</span><span class="n">ss2</span><span class="p">);</span>
  <span class="n">ia2</span> <span class="o">&gt;&gt;</span> <span class="n">new_pairwise_emd_obj</span> <span class="o">&gt;&gt;</span> <span class="n">new_corrdim</span><span class="p">;</span>

  <span class="c1">// print PairwiseEMD description</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">new_pairwise_emd_obj</span><span class="p">.</span><span class="n">description</span><span class="p">()</span>
            <span class="o">&lt;&lt;</span> <span class="s">&quot;Note that preprocessors are not currently preserved in serialized objects&quot;</span>
            <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>

  <span class="c1">// print out correlation dimensions</span>
  <span class="k">auto</span> <span class="n">corrdims</span><span class="p">(</span><span class="n">new_corrdim</span><span class="p">.</span><span class="n">corrdims</span><span class="p">());</span>
  <span class="k">auto</span> <span class="n">corrdim_bins</span><span class="p">(</span><span class="n">new_corrdim</span><span class="p">.</span><span class="n">corrdim_bins</span><span class="p">());</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">EMD         Corr. Dim.  Error</span><span class="se">\n</span><span class="s">&quot;</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">left</span><span class="p">;</span>
  <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">corrdims</span><span class="p">.</span><span class="n">first</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">setw</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">corrdim_bins</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
              <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">setw</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">corrdims</span><span class="p">.</span><span class="n">first</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
              <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">setw</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="n">corrdims</span><span class="p">.</span><span class="n">second</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
              <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>

<h3 id="theory_space_examplecpp">theory_space_example.cpp</h3>
<div class="codehilite"><pre><span></span><code><span class="c1">//------------------------------------------------------------------------</span>
<span class="c1">// This file is part of Wasserstein, a C++ library with a Python wrapper</span>
<span class="c1">// that computes the Wasserstein/EMD distance. If you use it for academic</span>
<span class="c1">// research, please cite or acknowledge the following works:</span>
<span class="c1">//</span>
<span class="c1">//   - Komiske, Metodiev, Thaler (2019) arXiv:1902.02346</span>
<span class="c1">//       https://doi.org/10.1103/PhysRevLett.123.041801</span>
<span class="c1">//   - Komiske, Metodiev, Thaler (2020) arXiv:2004.04159</span>
<span class="c1">//       https://doi.org/10.1007/JHEP07%282020%29006</span>
<span class="c1">//   - Boneel, van de Panne, Paris, Heidrich (2011)</span>
<span class="c1">//       https://doi.org/10.1145/2070781.2024192</span>
<span class="c1">//   - LEMON graph library https://lemon.cs.elte.hu/trac/lemon</span>
<span class="c1">//</span>
<span class="c1">// Copyright (C) 2019-2021 Patrick T. Komiske III</span>
<span class="c1">// </span>
<span class="c1">// This program is free software: you can redistribute it and/or modify</span>
<span class="c1">// it under the terms of the GNU General Public License as published by</span>
<span class="c1">// the Free Software Foundation, either version 3 of the License, or</span>
<span class="c1">// (at your option) any later version.</span>
<span class="c1">// </span>
<span class="c1">// This program is distributed in the hope that it will be useful,</span>
<span class="c1">// but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1">// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<span class="c1">// GNU General Public License for more details.</span>
<span class="c1">// </span>
<span class="c1">// You should have received a copy of the GNU General Public License</span>
<span class="c1">// along with this program.  If not, see &lt;https://www.gnu.org/licenses/&gt;.</span>
<span class="c1">//------------------------------------------------------------------------</span>

<span class="c1">// Wasserstein library</span>
<span class="cp">#include</span> <span class="cpf">&quot;Wasserstein.hh&quot;</span><span class="cp"></span>

<span class="c1">// classes and functions for reading/preparing events</span>
<span class="cp">#include</span> <span class="cpf">&quot;ExampleUtils.hh&quot;</span><span class="cp"></span>

<span class="c1">// `EMDFloat64` uses `double` for the floating-point type</span>
<span class="c1">// first template parameter is an Event type, second is a PairwiseDistance type</span>
<span class="k">using</span> <span class="n">EMD</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">EMDFloat64</span><span class="o">&lt;</span><span class="n">emd</span><span class="o">::</span><span class="n">EuclideanEvent2D</span><span class="p">,</span> <span class="n">emd</span><span class="o">::</span><span class="n">YPhiParticleDistance</span><span class="o">&gt;</span><span class="p">;</span>

<span class="c1">// `PairwiseEMD` is a templated class accepting a fully qualified `EMD` type</span>
<span class="k">using</span> <span class="n">PairwiseEMD</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">PairwiseEMD</span><span class="o">&lt;</span><span class="n">EMD</span><span class="o">&gt;</span><span class="p">;</span>

<span class="c1">// the `EuclideanParticle[N]D` classes provide a simple container for weighted particles</span>
<span class="k">using</span> <span class="n">EMDParticle</span> <span class="o">=</span> <span class="n">emd</span><span class="o">::</span><span class="n">EuclideanParticle2D</span><span class="o">&lt;&gt;</span><span class="p">;</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">**</span> <span class="n">argv</span><span class="p">)</span> <span class="p">{</span>

  <span class="c1">// load events</span>
  <span class="n">EventProducer</span> <span class="o">*</span> <span class="n">evp</span><span class="p">(</span><span class="n">load_events</span><span class="p">(</span><span class="n">argc</span><span class="p">,</span> <span class="n">argv</span><span class="p">));</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">evp</span> <span class="o">==</span> <span class="k">nullptr</span><span class="p">)</span>
    <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>

  <span class="c1">// demonstrate some EMD usage</span>
  <span class="kt">double</span> <span class="n">EMD_R</span> <span class="o">=</span> <span class="mf">0.4</span><span class="p">;</span>
  <span class="kt">double</span> <span class="n">EMD_beta</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="kt">bool</span> <span class="n">EMD_norm</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
  <span class="n">PairwiseEMD</span> <span class="n">pairwise_emd_obj</span><span class="p">(</span><span class="n">EMD_R</span><span class="p">,</span> <span class="n">EMD_beta</span><span class="p">,</span> <span class="n">EMD_norm</span><span class="p">);</span>

  <span class="c1">// preprocess events to center</span>
  <span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">preprocess</span><span class="o">&lt;</span><span class="n">emd</span><span class="o">::</span><span class="n">CenterWeightedCentroid</span><span class="o">&gt;</span><span class="p">();</span>

  <span class="c1">// print description</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">description</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>

  <span class="c1">// get vector of events</span>
  <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">EMDParticle</span><span class="o">&gt;&gt;</span> <span class="n">events</span><span class="p">;</span>

  <span class="c1">// loop over events and compute the EMD between each successive pair</span>
  <span class="n">evp</span><span class="o">-&gt;</span><span class="n">reset</span><span class="p">();</span>
  <span class="k">while</span> <span class="p">(</span><span class="n">evp</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">())</span>
    <span class="n">events</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">convert2event</span><span class="o">&lt;</span><span class="n">EMDParticle</span><span class="o">&gt;</span><span class="p">(</span><span class="n">evp</span><span class="o">-&gt;</span><span class="n">particles</span><span class="p">()));</span>

  <span class="c1">// run computation</span>
  <span class="n">pairwise_emd_obj</span><span class="p">(</span><span class="n">events</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">events</span><span class="p">.</span><span class="n">begin</span><span class="p">()</span> <span class="o">+</span> <span class="n">evp</span><span class="o">-&gt;</span><span class="n">num_accepted</span><span class="p">()</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span>
                   <span class="n">events</span><span class="p">.</span><span class="n">begin</span><span class="p">()</span> <span class="o">+</span> <span class="n">evp</span><span class="o">-&gt;</span><span class="n">num_accepted</span><span class="p">()</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">events</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>

  <span class="c1">// get max and min EMD value</span>
  <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">&gt;</span> <span class="o">&amp;</span> <span class="n">emds_raw</span><span class="p">(</span><span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">emds</span><span class="p">());</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;Min. EMD - &quot;</span> <span class="o">&lt;&lt;</span> <span class="o">*</span><span class="n">std</span><span class="o">::</span><span class="n">min_element</span><span class="p">(</span><span class="n">emds_raw</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">emds_raw</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span>
            <span class="o">&lt;&lt;</span> <span class="s">&quot;Max. EMD - &quot;</span> <span class="o">&lt;&lt;</span> <span class="o">*</span><span class="n">std</span><span class="o">::</span><span class="n">max_element</span><span class="p">(</span><span class="n">emds_raw</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">emds_raw</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span>
            <span class="o">&lt;&lt;</span> <span class="n">emds_raw</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="s">&quot; emds</span><span class="se">\n</span><span class="s">&quot;</span>
            <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span><span class="p">;</span>

  <span class="c1">// setup EMD object to compute cross section mover&#39;s distance</span>
  <span class="kt">double</span> <span class="n">SigmaMD_R</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="kt">double</span> <span class="n">SigmaMD_beta</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="kt">bool</span> <span class="n">SigmaMD_norm</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
  <span class="kt">bool</span> <span class="n">SigmaMD_do_timing</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>

  <span class="c1">// external dists are used by the default configuration</span>
  <span class="n">emd</span><span class="o">::</span><span class="n">EMDFloat64</span><span class="o">&lt;&gt;</span> <span class="n">sigmamd_obj</span><span class="p">(</span><span class="n">SigmaMD_R</span><span class="p">,</span> <span class="n">SigmaMD_beta</span><span class="p">,</span> <span class="n">SigmaMD_norm</span><span class="p">,</span> <span class="n">SigmaMD_do_timing</span><span class="p">);</span>

  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">sigmamd_obj</span><span class="p">.</span><span class="n">description</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span><span class="p">;</span>

  <span class="c1">// set distances</span>
  <span class="k">auto</span> <span class="n">emds</span><span class="p">(</span><span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">emds</span><span class="p">());</span>
  <span class="n">sigmamd_obj</span><span class="p">.</span><span class="n">ground_dists</span><span class="p">().</span><span class="n">resize</span><span class="p">(</span><span class="n">emds</span><span class="p">.</span><span class="n">size</span><span class="p">());</span>
  <span class="k">for</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">emds</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
    <span class="n">sigmamd_obj</span><span class="p">.</span><span class="n">ground_dists</span><span class="p">()[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">emds</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>

  <span class="c1">// form datasets</span>
  <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">&gt;</span> <span class="n">weights0</span><span class="p">(</span><span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">nevA</span><span class="p">(),</span> <span class="mi">1</span><span class="p">),</span>
                      <span class="n">weights1</span><span class="p">(</span><span class="n">pairwise_emd_obj</span><span class="p">.</span><span class="n">nevB</span><span class="p">(),</span> <span class="mi">1</span><span class="p">);</span>

  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;Running computation ...&quot;</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>

  <span class="c1">// run computation</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;Cross-section Mover&#39;s Distance : &quot;</span> <span class="o">&lt;&lt;</span> <span class="n">sigmamd_obj</span><span class="p">(</span><span class="n">weights0</span><span class="p">,</span> <span class="n">weights1</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span>
            <span class="o">&lt;&lt;</span> <span class="s">&quot;Done in &quot;</span> <span class="o">&lt;&lt;</span> <span class="n">sigmamd_obj</span><span class="p">.</span><span class="n">duration</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">;</span>

  <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>

            </div>
          </div><footer>
    <div class="rst-footer-buttons" role="navigation" aria-label="Footer Navigation">
        <a href="../demos/" class="btn btn-neutral float-left" title="Python Demos"><span class="icon icon-circle-arrow-left"></span> Previous</a>
        <a href="../faqs/" class="btn btn-neutral float-right" title="FAQs">Next <span class="icon icon-circle-arrow-right"></span></a>
    </div>

  <hr/>

  <div role="contentinfo">
    <!-- Copyright etc -->
      <p>Copyright (C) 2019-2021 Patrick T. Komiske III</p>
  </div>

  Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>

        </div>
      </div>

    </section>

  </div>

  <div class="rst-versions" role="note" aria-label="Versions">
  <span class="rst-current-version" data-toggle="rst-current-version">

        <span>
          <a href="https://github.com/thaler-lab/Wasserstein/" class="fa fa-github" style="color: #fcfcfc"> GitHub</a>
        </span>


      <span><a href="../demos/" style="color: #fcfcfc">&laquo; Previous</a></span>


      <span><a href="../faqs/" style="color: #fcfcfc">Next &raquo;</a></span>

  </span>
</div>
    <script>var base_url = '..';</script>
    <script src="../js/theme_extra.js" defer></script>
    <script src="../js/theme.js" defer></script>
      <script src="../js/extra.js" defer></script>
      <script src="https://polyfill.io/v3/polyfill.min.js?features=es6" defer></script>
      <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" defer></script>
      <script src="../search/main.js" defer></script>
    <script defer>
        window.onload = function () {
            SphinxRtdTheme.Navigation.enable(true);
        };
    </script>

</body>
</html>
